<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<body></body>
<script>
function createTarget() {
  return document.body.appendChild(document.createElement('div'));
}

function setTaintedValue(target, property, value) {
  target.animate({[property]: value}, {fill: 'forwards'});
  assert_equals(getComputedStyle(target).getPropertyValue(property), value,
      `Tainted value ${value} set on ${property} by animation`);
}

function testTaintedSubstitution(target, varValue, {animationName, customProperty}) {
  target.style.animationName = varValue;
  target.style.setProperty('--taint-accepted', varValue);
  assert_equals(getComputedStyle(target).animationName, animationName,
      `${varValue} with tainted values ommitted`);
  assert_equals(getComputedStyle(target).getPropertyValue('--taint-accepted'), customProperty,
      `${varValue} with tainted values accepted`);
}

test(() => {
  var target = createTarget();
  setTaintedValue(target, '--tainted', 'tainted');
  testTaintedSubstitution(target, 'var(--tainted)', {
    animationName: 'none',
    customProperty: 'tainted',
  });
}, 'Animation tainted values are omitted in CSS property animation-name');

test(() => {
  var target = createTarget();
  setTaintedValue(target, '--tainted-first', 'tainted');
  target.style.setProperty('--tainted-second', 'var(--tainted-first)');
  testTaintedSubstitution(target, 'var(--tainted-second)', {
    animationName: 'none',
    customProperty: 'tainted',
  });
}, 'Chained animation tainted values are omitted in CSS property animation-name');

test(() => {
  var parent = createTarget();
  var child = parent.appendChild(document.createElement('div'));
  setTaintedValue(parent, '--tainted', 'tainted');
  testTaintedSubstitution(child, 'var(--tainted)', {
    animationName: 'none',
    customProperty: 'tainted',
  });
}, 'Inherited animation tainted values are omitted in CSS property animation-name');

test(() => {
  var target = createTarget();
  setTaintedValue(target, '--tainted', 'tainted');
  testTaintedSubstitution(target, 'var(--tainted, fallback)', {
    animationName: 'fallback',
    customProperty: 'tainted',
  });
}, 'Animation tainted values trigger var fallbacks in CSS property animation-name');

test(() => {
  var target = createTarget();
  setTaintedValue(target, '--tainted', 'tainted');
  testTaintedSubstitution(target, 'var(--unknown, var(--tainted))', {
    animationName: 'none',
    customProperty: ' tainted',
  });
}, 'Animation tainted fallback values are omitted in CSS property animation-name');
</script>
